﻿using Qiniu.Http;
using Qiniu.Storage;
using Qiniu.Util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace IPBoss.Copyright.UtilityHelper
{
    public class QinniuFileHelper
    {


        private string access_key = ConfigHelper.GetAppSetting("AccessKey");
        private string secret_key = ConfigHelper.GetAppSetting("SecretKey");
        private string QinNiuRegion = ConfigHelper.GetAppSetting("QinNiuRegion");
        private string zxr_test = ConfigHelper.GetAppSetting("AppConfig:QinNiuRegion");


        /// <summary>
        /// 文件存储类型，普通存储:0，低频存储:1
        /// </summary>
        private int file_save_type = 1;
        private bool uploadByCdn = true;
        private string _DomainsName = "";
        private Mac mac = null;

        private Config config = null;
        public QinniuFileHelper(string domains_name = "deliver")
        {

            if (domains_name == "deliver" && !string.IsNullOrEmpty(QinNiuRegion))
            {
                domains_name = QinNiuRegion;
            }


            mac = new Mac(access_key, secret_key);
            //set bucket manager and upload manager config
            _DomainsName = domains_name;
            config = new Config();
            config.UseCdnDomains = uploadByCdn;
            config.PutThreshold = 4;

        }


        /// <summary>
        /// 检查文件是否存在，使用BucketManager获取文件信息的方式
        /// </summary>
        /// <param name="filekey"></param>
        /// <returns></returns>
        public bool CheckFileExist(string filekey)
        {
            BucketManager bucketManager = new BucketManager(mac, config);
            StatResult statRet = bucketManager.Stat(_DomainsName, filekey);
            return statRet.Code == 200;

        }


        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="localFile">本地文件完全地址(或当前服务器能访问到的共享文件)</param>
        /// <param name="fileKey">文件存储key，20190508/I00003/A201904230518-XR190508001892-商标代购合同.pdf </param>
        /// <param name="IsNewFile">是否是新文件，true：创建新文件，false：覆盖上传</param>
        /// <param name="IsTest">是否是测试，设置文件一天后删除</param>
        /// <returns></returns>
        public string UploadFile(string localFile, string fileKey, bool IsNewFile = false, bool IsTest = false)
        {
            string key = "";
            try
            {
                UploadManager uploadManager = new UploadManager(config);

                // 上传策略配置
                PutPolicy putPolicy = new PutPolicy();

                putPolicy.Scope = IsNewFile ? _DomainsName : string.Format("{0}:{1}", _DomainsName, fileKey);

                putPolicy.SetExpires(24 * 30 * 3600);
                //set file type
                putPolicy.FileType = file_save_type;
                if (IsTest)
                {
                    // 文件上传完毕后，在多少天后自动被删除
                    putPolicy.DeleteAfterDays = 1;
                }
                Auth auth = new Auth(mac);
                string uptoken = auth.CreateUploadToken(putPolicy.ToJsonString());
                HttpResult uploadResult = uploadManager.UploadFile(localFile, fileKey, uptoken, null);

                if (uploadResult.Code == 200)
                {
                    QiniuUploadFileResult result = JsonHelper.Deserialize<QiniuUploadFileResult>(uploadResult.Text);
                    key = result.key;
                }
            }
            catch (Exception ex)
            {
                Log4NetHelper.Error("UploadFile", " localFile:" + localFile + " fileKey:" + fileKey, ex);
            }

            return key;

        }

        /// <summary>
        /// 以流的形式上传
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="fileKey"></param>
        /// <param name="IsNewFile"></param>
        /// <param name="IsTest"></param>
        /// <returns></returns>
        public string UploadStream(Stream stream, string fileKey, bool IsNewFile = false, bool IsTest = false)
        {
            string key = "";
            UploadManager uploadManager = new UploadManager(config);

            // 上传策略配置
            PutPolicy putPolicy = new PutPolicy();

            putPolicy.Scope = IsNewFile ? _DomainsName : string.Format("{0}:{1}", _DomainsName, fileKey);

            putPolicy.SetExpires(24 * 30 * 3600);
            //set file type
            putPolicy.FileType = file_save_type;
            if (IsTest)
            {
                // 文件上传完毕后，在多少天后自动被删除
                putPolicy.DeleteAfterDays = 1;
            }
            Auth auth = new Auth(mac);
            string uptoken = auth.CreateUploadToken(putPolicy.ToJsonString());

            // 包含两个参数，并且都有默认值
            // 参数1(bool): uploadFromCDN是否从CDN加速上传，默认否
            // 参数2(enum): chunkUnit上传分片大小，可选值128KB,256KB,512KB,1024KB,2048KB,4096KB            
            HttpResult uploadResult = uploadManager.UploadStream(stream, fileKey, uptoken, null);

            if (uploadResult.Code == 200)
            {
                QiniuUploadFileResult result = JsonHelper.Deserialize<QiniuUploadFileResult>(uploadResult.Text);
                key = result.key;
            }
            return key;

        }

        /// <summary>
        /// 以byte上传
        /// </summary>
        /// <param name="data"></param>
        /// <param name="fileKey"></param>
        /// <param name="IsNewFile"></param>
        /// <param name="IsTest"></param>
        /// <returns></returns>
        public string UploadData(byte[] data, string fileKey, bool IsNewFile = false, bool IsTest = false)
        {
            string key = "";
            UploadManager uploadManager = new UploadManager(config);

            // 上传策略配置
            PutPolicy putPolicy = new PutPolicy();

            putPolicy.Scope = IsNewFile ? _DomainsName : string.Format("{0}:{1}", _DomainsName, fileKey);

            putPolicy.SetExpires(24 * 30 * 3600);
            //set file type
            putPolicy.FileType = file_save_type;
            if (IsTest)
            {
                // 文件上传完毕后，在多少天后自动被删除
                putPolicy.DeleteAfterDays = 1;
            }
            Auth auth = new Auth(mac);
            string uptoken = auth.CreateUploadToken(putPolicy.ToJsonString());

            // 包含两个参数，并且都有默认值
            // 参数1(bool): uploadFromCDN是否从CDN加速上传，默认否
            // 参数2(enum): chunkUnit上传分片大小，可选值128KB,256KB,512KB,1024KB,2048KB,4096KB            
            HttpResult uploadResult = uploadManager.UploadData(data, fileKey, uptoken, null);

            if (uploadResult.Code == 200)
            {
                QiniuUploadFileResult result = JsonHelper.Deserialize<QiniuUploadFileResult>(uploadResult.Text);
                key = result.key;
            }
            return key;

        }

        /// <summary>
        /// 创建一个私有空间的访问路径地址
        /// <param name="rawUrl">文件路径</param>
        /// <param name="domain">访问的域名，http://contract.cdn.iprboss.com</param>
        /// </summary>
        public string CreatePrivateUrl(string rawUrl, string domain = "http://contract.cdn.iprboss.com")
        {
            if (domain == "http://deliver.cdn.iprboss.com" && !string.IsNullOrEmpty(zxr_test))
            {
                domain = zxr_test;
            }
            string accUrl = DownloadManager.CreatePrivateUrl(mac, domain, rawUrl, 3600);
            // 接下来可以使用accUrl来下载文件
            return accUrl;

        }
        public string CreatePrivateUrl(string rawUrl)
        {

            string newdomain = "http://deliver.cdn.iprboss.com";
            if (!string.IsNullOrEmpty(zxr_test))
            {
                newdomain = zxr_test;
            }

            string newRawUrl = rawUrl;
            if (rawUrl.Length >= 7 && rawUrl.Substring(0, 7).ToLower() == "?domain")
            {
                int b = rawUrl.IndexOf("=") + 1;
                int e = rawUrl.IndexOf("&");
                int l = e - b;
                string urltype = rawUrl.Substring(b, l);
                newRawUrl = rawUrl.Substring(rawUrl.LastIndexOf("=") + 1);
                newdomain = ConfigHelper.GetAppSetting(urltype);
            }

            string accUrl = DownloadManager.CreatePrivateUrl(mac, newdomain, newRawUrl, 3600);
            TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            accUrl += "&r=" + Convert.ToInt64(ts.TotalSeconds).ToString();
            // 接下来可以使用accUrl来下载文件
            return accUrl;

        }
        /// <summary>
        /// 创建一个公用有空间的访问路径地址
        /// </summary>
        /// <param name="rawUrl"></param>
        /// <param name="domain"></param>
        /// <returns></returns>
        public string CreatePublishUrl(string rawUrl, string domain = "http://contract.cdn.iprboss.com")
        {
            string accUrl = DownloadManager.CreatePublishUrl(domain, rawUrl);
            // 接下来可以使用accUrl来下载文件
            return accUrl;

        }

        public string Md5Hash(string str)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] data = Encoding.UTF8.GetBytes(str);
            byte[] hashData = md5.ComputeHash(data);
            StringBuilder sb = new StringBuilder(hashData.Length * 2);
            foreach (byte b in hashData)
            {
                sb.AppendFormat("{0:x2}", b);
            }
            return sb.ToString();
        }

    }


    public class QiniuUploadFileResult
    {
        public string hash { get; set; }
        public string key { get; set; }
    }

}
